package com.zhxq.ai.service.impl;

import com.alibaba.dashscope.aigc.multimodalconversation.AudioParameters;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.zhxq.ai.service.TTSService;
import com.zhxq.ai.websocket.TTSServer;
import groovy.util.logging.Slf4j;
import io.reactivex.Flowable;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.zhxq.framework.datasource.DynamicDataSourceContextHolder.log;

@Service
@RequiredArgsConstructor
@Slf4j
public class TTSServiceImpl implements TTSService {

    private static final String MODEL = "qwen-tts"; // 文本转语音模型

    private final SpeechSynthesizer synthesizer;

    private final TTSServer ttsServer;

    @Override
    public String call(String text) throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey("sk-0f393ee8c13c4e87ab6da00b977fffc2")
                .model(MODEL)
                .text(text)
                .voice(AudioParameters.Voice.CHERRY)
                .build();
        MultiModalConversationResult result = conv.call(param);
        return result.getOutput().getAudio().getUrl();
    }

    @Override
    public Flowable<MultiModalConversationResult> streamCall(String text) throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .apiKey("sk-0f393ee8c13c4e87ab6da00b977fffc2")
                .model(MODEL)
                .text(text)
                .voice(AudioParameters.Voice.CHERRY)
                .build();
        return conv.streamCall(param);
    }

    @Override
    public void streamInputOutput(Flowable<String> inputStream, String chatId) throws ApiException, NoApiKeyException {
        synthesizer.streamingCallAsFlowable(inputStream)
                .buffer(5, TimeUnit.MILLISECONDS, 20) // 合并 5 帧
                .subscribe(results -> {
                    results.stream()
                            .map(SpeechSynthesisResult::getAudioFrame)
                            .filter(Objects::nonNull)
                            .forEach(audioFrame -> ttsServer.sendAudio(chatId, audioFrame));
                }, throwable -> {
                    log.info("TTS 流处理异常", throwable);
                    ttsServer.closeSession(chatId); // 出错关闭 session
                }, () -> {
                    log.info("TTS 流已完成，关闭连接");
                    ttsServer.sendEndSignal(chatId);
                    ttsServer.closeSession(chatId);
                });
    }
}
